#include <iostream>
#include <memory>
#include <time.h>

#include "Socket.hpp"
#include "Protocol.hpp"

int main(int argc, char *argv[])
{
    if (argc != 3)
    {
        std::cout << "Usage->  " << argv[0] << " serverip serverport" << std::endl;
        return 0;
    }

    std::string serverip = argv[1];
    uint16_t serverport = std::stoi(argv[2]);

    Net_work::Socket *s = new Net_work::TcpSocket();

    if (!s->BuildConnectSocket(serverip, serverport))
    {
        std::cerr << "connet " << serverip << ":" << serverport << "error!" << std::endl;
    }
    else
        std::cout << "connet " << serverip << ":" << serverport << "success!" << std::endl;

    std::unique_ptr<Protocol::Factory> factory = std::make_unique<Protocol::Factory>();

    // std::shared_ptr<Protocol::Request> req = factory->BuildRequest(10, 20, '+');

    srand(time(nullptr) ^ getpid());
    const std::string opers = "/*+-^&";


    
    while (true)
    {
        // req->Inc(); // 自增
        // send(s->GetSockFd(), &(*req), sizeof(*req), 0);

        int x = rand() % 100;

        usleep(rand() % 700);

        int y = rand() % 3245;

        usleep(rand() % 340);

       

        char oper = opers[rand() % opers.size()];

        std::shared_ptr<Protocol::Request> req = factory->BuildRequest(x, y, oper);

        

        //  对请求进行序列化
        std::string request_str;
        req->Serialize(&request_str);

        // 添加报头
        request_str = Protocol::Encode(request_str);

        //  发送
        s->Send(request_str);

        
          
        std::string Response_str;

        

        while (true)
        {
            // 接收请求
            s->Recv(&Response_str, 1024);

            // 报文解析
            std::string Message;
            if(!Protocol::Decode(Response_str, &Message))
            {
                exit(1);
                continue; 
            }
      
            auto resp = factory->BuildResponse();
            resp->DeSerialize(Message);

            std::cout<< req->DebugPrint() <<" = "<<resp->Get_result()<<" ["<<resp->Get_code()<<"]"<<std::endl;
            break;
        }

        sleep(1);
    }

    s->CloseSocket();
    return 0;
}